<!--
 * @Date: 2024-07-22 14:38:10
 * @Author: LiSong
 * @LastEditors: LiSong
 * @LastEditTime: 2024-12-04 14:59:36
 * @Description: 部件面板
-->
<template>
  <div class="widget-panel-wrapper">
    <div class="widget-panel-container">
        <el-tabs v-model="tabsStore.activeTab" class="widget-panel-tabs">
          <el-scrollbar
            class="side-scroll-bar"
            :style="{ height: '100%' }"
          >
          <el-tab-pane name="componentLib">
            <template #label>
              <div class="panel-tabs-header">
                <VfIcon class="header-icon" name="iv-icon-set-up" />
                <span class="header-content">{{ i18n.$st('designer.componentLib') }}</span>
              </div>
            </template>
            <el-collapse
              class="widget-collapse"
              v-model="collapseStore.activeNames"
            >
              <el-collapse-item
                v-for="item in collapseItems" :key="item.id"
                :name="item.type" :title="item.title"
              >
                <draggable
                  :="draggableAttrs"
                  :list="item.widgets"
                  :move="(origin) => onDraggableMove(origin, item.type)"
                  :clone="(origin) => onDraggableClone(origin, item.type)"
                >
                  <template #item="{ element: ctn }">
                    <li class="field-widget-item"
                      :title="ctn.displayName" 
                      @dblclick="widgetItemDbClick(ctn, item.type)"
                    >
                      <VfIcon :name="ctn.icon" color="#7c7d82"/>
                      <span>{{ ctn.displayName }}</span>
                    </li>
                  </template>
                </draggable>
              </el-collapse-item>
            </el-collapse>
          </el-tab-pane>
          </el-scrollbar>
        </el-tabs>
    </div>
  </div>
</template>

<script setup>

import { i18n } from '@/utils/i18n';
import { generateId } from '@/utils/util';
import { reactive, inject, computed } from 'vue';

import {
  basicFields as BFS,
  customFields as CFS,
  advancedFields as AFS,
  containerFields as CONS,
} from './widgetsConfig';

// 自定义属性
const props = defineProps({
  designer: Object
})

// 来自父级定义的相关内容
const getBannedWidgets = inject('getBannedWidgets')
const getDesignerConfig = inject('getBannedWidgets')

// 不同类型的组件的枚举对象
const WidgetEnums = {
  'BASIC': { code: 'basic' },
  'CUSTOM': { code: 'custom' },
  'ADVANCED': { code: 'advanced' },
  'CONTAINER': { code: 'container' },
}
// tabs组件的数据集
const tabsStore = reactive({
  // 选中的tab
  activeTab: 'componentLib',
})

// 折叠面板组件的数据集
const collapseStore = reactive({
  activeNames: [],
})
// 折叠面板的列表数据
const collapseItems = computed(() => {
  // 容器组件
  const rqWidgets = CONS.map(config => {
    return {
      key: generateId(), ...config,
      displayName: getWidgetI18nSt2Name(config.type)
    }
  }).filter(config => {
    return !config.internal && !validateBanned(config.type)
  })

  // 表单组件
  const bdWidgets = BFS.map(config => {
    return {
      key: generateId(), ...config,
      displayName: getWidgetI18nSt2Name(config.type)
    }
  }).filter(config => {
    return !validateBanned(config.type)
  })
  
  const returnResult = [
    { id: generateId(), type: WidgetEnums.CONTAINER.code, title: getCollapseI18StName('containerTitle'), widgets: rqWidgets },
    { id: generateId(), type: WidgetEnums.BASIC.code, title: getCollapseI18StName('basicFieldTitle'), widgets: bdWidgets },
  ]
  // 高级字段
  const gjWidgets = AFS.map(config => {
    return { key: generateId(), ...config, displayName: getWidgetI18nSt2Name(config.type) }
  }).filter(config => {
    return !validateBanned(config.type)
  })
  if (gjWidgets.length > 0) {
    returnResult.push({ id: generateId(), type: WidgetEnums.ADVANCED.code, title: getCollapseI18StName('advancedFieldTitle'), widgets: gjWidgets })
  }
  // 扩展字段
  const kzWidgets = CFS.map(config => {
    return { key: generateId(), ...config, displayName: getWidgetI18nSt2Name(config.type) }
  }).filter(config => {
    return !validateBanned(config.type)
  })
  if (kzWidgets.length > 0) {
    returnResult.push({ id: generateId(), type: WidgetEnums.CUSTOM.code, title: getCollapseI18StName('customFieldTitle'), widgets: kzWidgets })
  }

  // 设置展开的折叠面板
  collapseStore.activeNames = returnResult.map(item => item.type)

  return returnResult
})

/**
 * 验证是否为禁用组件
 *
 * @param name 组件名称
 */
const validateBanned = (name) => {
  return getBannedWidgets().indexOf(name) > -1
}
/**
 * 组件元素双击的方法
 * 
 * @param origin 配置
 * @param type 类型 WidgetEnums
 */
const widgetItemDbClick = (origin, type) => {
  let result = ''
  const { designer } = props
  switch(type) {
    case WidgetEnums.BASIC.code:
    case WidgetEnums.CUSTOM.code:
    case WidgetEnums.ADVANCED.code:
      result = designer.addFieldByDbClick(origin);
      break;
    case WidgetEnums.CONTAINER.code:
      result = designer.addContainerByDbClick(origin);
      break;
    default:
      break;
  }
  return result
}
/**
 * 获取折叠面板i18定义的信息（单字段）
 * 
 * @param k 关键词
 */
const getCollapseI18StName = (k) => {
  return i18n.$st(`designer.${k}`)
}
/**
 * 获取折叠面板i18定义的信息（双字段）
 * 
 * @param k 关键词
 */
const getWidgetI18nSt2Name = (k) => {
  return i18n.$st2(`designer.widgetLabel.${k}`, `extension.widgetLabel.${k}`)
}

// 拖拽组件属性定义
const draggableAttrs = reactive({
  tag: 'ul',
  sort: false,
  group: { name: 'dragGroup', pull: 'clone', put: false },
  itemKey: 'key',
  ghostClass: 'ghost',
})
/**
 * 拖拽组件移动时触发
 * 
 * @param origin 配置
 * @param type 类型 WidgetEnums
 */
const onDraggableMove = (origin, type) => {
  let result = ''
  const { designer } = props
  switch(type) {
    case WidgetEnums.BASIC.code:
    case WidgetEnums.CUSTOM.code:
    case WidgetEnums.ADVANCED.code:
      result = designer.checkFieldMove(origin);
      break;
    case WidgetEnums.CONTAINER.code:
      result = designer.checkWidgetMove(origin);
      break;
    default:
      break;
  }
  return result
}
/**
 * 拖拽组件复制时触发
 * 
 * @param origin 配置
 * @param type 类型 WidgetEnums
 */
const onDraggableClone = (origin, type) => {
  let result = ''
  const { designer } = props
  switch(type) {
    case WidgetEnums.BASIC.code:
    case WidgetEnums.CUSTOM.code:
    case WidgetEnums.ADVANCED.code:
      result = designer.copyNewFieldWidget(origin);
      break;
    case WidgetEnums.CONTAINER.code:
      result = designer.copyNewContainerWidget(origin);
      break;
    default:
      break;
  }
  return result
}

</script>

<style lang="scss" scoped>
.widget-panel-wrapper {
  height: 100%;
}
.widget-panel-container {
  height: 100%;
  padding-bottom: 10px;
}
.widget-panel-tabs {
  height: 100%;
  display: flex;
  flex-direction: column-reverse;
  :deep(.el-tabs__header) {
    margin-bottom: 0;
  }
  :deep(.el-tabs__content) {
    flex: 1;
    overflow: auto;
  }
  .panel-tabs-header {
    padding: 0 20px;
    .header-icon {
      margin-left: 0;
    }
  }
}

// 小部件元素的间隔
$itemGutter: 10px;
$itemWidth: #{calc((100% - $itemGutter) / 2)};
.widget-collapse {
  border-top-width: 0;

  :deep(.el-collapse-item__header) {
    padding-left: 8px;
    font-style: italic;
    font-weight: bold;
  }

  :deep(.el-collapse-item__content) {
    padding-bottom: 6px;
    ul {
      display: flex;
      margin: 0;
      padding: 0 8px;
      justify-content: flex-start;
      align-items: center;
      flex-wrap: wrap;
      &:after {
        content: '';
        display: block;
        clear: both;
      }
      .field-widget-item,
      .container-widget-item {
        flex: 1;
        cursor: move;
        
        margin: #{0 $itemGutter $itemGutter 0};
        padding: 0 8px;
        
        border: 1px solid #d9d9d9;
        box-sizing: border-box;
        border-radius: 5px;
        
        overflow: hidden;
        white-space: nowrap;
        text-overflow: ellipsis;

        height: 32px;
        line-height: 32px;
        width: $itemWidth;
        min-width: $itemWidth;
        max-width: $itemWidth;
        
        .icon-color{
          -webkit-font-smoothing: antialiased;
          color: #7c7d82;
        }
        &:nth-child(2n + 2) {
          margin-right: 0;
        }
        &:hover {
          color: $--color-primary;
          border-color: $--color-primary;
          .icon-color {
            color: $--color-primary;
          }
        }
      }
      .drag-handler {
        position: absolute;
        top: 0;
        left: 160px;
        background-color: #dddddd;
        border-radius: 5px;
        padding-right: 5px;
        font-size: 11px;
        color: #666666;
      }
    }
  }
}

.side-scroll-bar {
  :deep(.el-scrollbar__wrap) {
    overflow-x: hidden;
  }
  :deep(.el-tabs__nav) {
    margin-left: 8px;
  }
}

</style>
